﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Services;
using System.Configuration;

namespace DynaBoard
{
    public partial class PostPage : Page
    {
        private static ExpiringObjectCache<string, object> floodPreventionIpCache =
            new ExpiringObjectCache<string, object>(TimeSpan.Parse(ConfigurationManager.AppSettings["FloodLimit"]));

        protected Post op;
        protected Board board;

        protected string replyAuthorName;
        protected string replyAuthorEmail;

        public static string UrlToPost(int id)
        {
            return "/Post.aspx?id=" + id.ToString();
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            int postId;

            try
            {
                postId = int.Parse(Request.QueryString["id"]);
            }
            catch (ArgumentException)
            {
                return;
            }


            this.op = Post.FromId(postId);
            this.board = Board.FromPostId(this.op.Id);

            var author = Post.Author(this.op.Id, new RequestorAddress());

            if (author != null)
            {
                this.replyAuthorName = author.Name;
                this.replyAuthorEmail = author.Email;
            }
        }

        [WebMethod(CacheDuration=60)]
        public static object[] FetchThread(int postId, int[] gottenPosts)
        {
            string opAuthorIp = Post.AuthorIpFromId(postId);

            return (from post in Post.FetchThread(postId, gottenPosts)
                    select new
                    {
                        Id = post.Id,
                        ParentId = post.ParentPostId,
                        UnixTime = new UnixTime(post.PostedUtc).Milliseconds,
                        Title = post.Title,
                        Body = post.Body,
                        Author = post.AuthorName,
                        Email = post.AuthorEmail,
                        Op = (post.AuthorIp == opAuthorIp),
                        Votes = Vote.Count(post.Id)
                    }).ToArray();
        }

        [WebMethod]
        public static int SubmitPost(string postBody, int postId, string authorName, string authorEmail)
        {
            var ipAddress = new RequestorAddress();

            if (PostPage.floodPreventionIpCache[ipAddress] == null)
            {
                PostPage.floodPreventionIpCache.Add(ipAddress, new object());
                return Post.SubmitReply(postId, postBody, authorName, authorEmail, ipAddress);
            }
            else
            {
                throw new PostSubmissionException
                    ("Cannot submit more than one post every " + PostPage.floodPreventionIpCache.LifeSpan.TotalSeconds + " seconds.");
            }
        }

        [WebMethod]
        public static void VoteFor(int postId)
        {
            Vote.Register(postId, new RequestorAddress(), 1);
        }

        [WebMethod]
        public static void VoteAgainst(int postId)
        {
            Vote.Register(postId, new RequestorAddress(), -1);
        }

        [WebMethod]
        public static KeyValuePair<int, int>[] Votes(int[] posts)
        {
            using (var db = DynaBoardDataContext.Create)
            {
                var votes = from vote in db.Vote
                            where posts.Contains(vote.PostId)
                            select new KeyValuePair<int, int>
                            (
                                vote.PostId,
                                (from v in db.Vote
                                 where v.PostId == vote.PostId
                                 select v.Vote1).AsEnumerable().Sum()
                            );

                return votes.ToArray();
            }
        }

        [WebMethod]
        public static object ThreadUrl()
        {
            return "crap";
        }
    }
}
